﻿using ChuanYe.WorkLogManagement.EF.SqlServer;
using ChuanYe.WorkLogManagement.Model;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Transactions;

namespace ChuanYe.WorkLogManagement.BLL
{
    public class UserInfoBLL
    {
        #region 构造单例
        private UserInfoBLL() { }
        private static UserInfoBLL _instance;
        public static UserInfoBLL Instance
        {
            get
            {
                return _instance ?? (_instance = new UserInfoBLL());
            }
        }
        #endregion

        /// <summary>
        /// 增加
        /// </summary>
        /// <param name="info"></param>
        /// <returns>UserID</returns>
        public int Add(UserInfo info)
        {
            using (WorkLogContext context = new WorkLogContext())
            {
                context.UserInfo.Add(info);
                context.Entry<UserInfo>(info).State = EntityState.Added;
                context.SaveChanges();
                return info.UserID;
            }
        }

        /// <summary>
        /// 获取单条
        /// </summary>
        public UserInfoModel Get(int userID,string accountName,string phone)
        {
            using (WorkLogContext context = new WorkLogContext())
            {
                var linq = from a in context.UserInfo
                           join b in context.DepartmentInfo on a.DepartmentID equals b.DepartmentID
                           into c
                           let d = c.FirstOrDefault()
                           join h in context.PositionInfo on a.PositionID equals h.PositionID
                           into i
                           let j = i.FirstOrDefault()
                           select new UserInfoModel{
                               UserID=a.UserID,
                               AccountName=a.AccountName,
                               RealName=a.RealName,
                               Password=a.Password,
                               MobilePhone= a.MobilePhone,
                               DepartmentID= a.DepartmentID,
                               DepartmentName= d == null ? string.Empty:d.DepartmentName,
                               PositionID = a.PositionID,
                               PositionName = j == null ? string.Empty : j.PositionName,
                               IsManager=a.IsManager ,
                           };
                if (userID > 0)
                {
                    linq = linq.Where(p=>p.UserID==userID);
                }
                if (!string.IsNullOrEmpty(accountName))
                {
                    linq = linq.Where(p => p.AccountName == accountName  || p.MobilePhone==accountName);
                }
                if (!string.IsNullOrEmpty(phone))
                {
                    linq = linq.Where(p => p.MobilePhone == phone);
                }
                return linq.FirstOrDefault();
            }
        }

        public void Remove(int userID)
        {
            using (WorkLogContext context = new WorkLogContext())
            {
                using (TransactionScope trans = new TransactionScope())
                {
                    //删除用户
                    var existUser = context.UserInfo.Where(p => p.UserID == userID).FirstOrDefault();
                    if (existUser != null)
                    {
                        context.UserInfo.Add(existUser);
                        context.Entry<UserInfo>(existUser).State = EntityState.Deleted;
                    }

                    //删除用户关系
                    var existRelList= context.UserPowerInfo.Where(p => p.UserID == userID || p.ChilderID==userID).ToList();
                    foreach (var item in existRelList)
                    {
                        context.UserPowerInfo.Add(item);
                        context.Entry<UserPowerInfo>(item).State = EntityState.Deleted;
                    }

                    //删除工作日志
                    var existWorkList = context.WorkInfo.Where(p => p.UserID == userID ).ToList();
                    foreach (var work in existWorkList)
                    {
                        context.WorkInfo.Add(work);
                        context.Entry<WorkInfo>(work).State = EntityState.Deleted;
                    }
                    context.SaveChanges();
                    trans.Complete();
                }
            }
        }

        public void AddChilderUserID(int userID, List<int> childerUserIDs)
        {
            using (WorkLogContext context = new WorkLogContext())
            {
                using (TransactionScope trans = new TransactionScope())
                {
                    foreach (var item in childerUserIDs)
                    {
                        if (userID > 0 && item > 0)
                        {

                            var exist = context.UserPowerInfo.Where(p =>p.UserID==userID &&p.ChilderID == item).FirstOrDefault();
                            if (exist == null)
                            {
                                var info = new UserPowerInfo();
                                info.UserID = userID;
                                info.ChilderID = item;
                                info.AddTime = DateTime.Now;
                                context.UserPowerInfo.Add(info);
                                context.Entry<UserPowerInfo>(info).State = EntityState.Added;
                            }
                        }
                    }
                    context.SaveChanges();
                    trans.Complete();
                }
            }
        }

        public void RemoveChilderUserID(int userID, List<int> childerUserIDs)
        {
            using (WorkLogContext context = new WorkLogContext())
            {
                using (TransactionScope trans = new TransactionScope())
                {
                    foreach (var item in childerUserIDs)
                    {
                        if (userID > 0 && item > 0)
                        {
                            var exist = context.UserPowerInfo.Where(p => p.UserID==userID && p.ChilderID == item).FirstOrDefault();
                            if (exist != null)
                            {
                                context.UserPowerInfo.Add(exist);
                                context.Entry<UserPowerInfo>(exist).State = EntityState.Deleted;
                            }
                        }
                    }
                    context.SaveChanges();
                    trans.Complete();
                }
            }
        }

        public dynamic GetSubUserInfo(int userID)
        {
            using (WorkLogContext context = new WorkLogContext())
            {
                var linq = from a in context.UserPowerInfo
                                      join b in context.UserInfo on a.ChilderID equals b.UserID
                                      into c
                                      let d = c.FirstOrDefault()
                                      join e in context.DepartmentInfo on d.DepartmentID equals e.DepartmentID
                                      into  f
                                      let g=f.FirstOrDefault()
                                      join h in context.PositionInfo on d.PositionID equals h.PositionID
                                      into i
                                      let j = i.FirstOrDefault()
                                      select new {
                                          SlefID=a.UserID,
                                          a.ChilderID,
                                          a.PowerID,
                                          d.RealName,
                                          d.PositionID,
                                          g.DepartmentID,
                                          g.DepartmentName,
                                          j.PositionName,
                                          d.IsManager,
                                      };
                if (userID > 0)
                {
                    linq = linq.Where(p => p.SlefID == userID);
                }
                return linq.ToList();
            }
        }

        public int ChangePassword(int userID, string oldPassword, string newPassword)
        {
            using (WorkLogContext context = new WorkLogContext())
            {
                var exist = context.UserInfo.Where(p=>p.UserID==userID).FirstOrDefault();
                if (exist == null)
                {
                    return -1;
                }
                else if (exist.Password != oldPassword)
                {
                    return 0;
                }
                else
                {
                    exist.Password = newPassword;
                    context.UserInfo.Add(exist);
                    context.Entry<UserInfo>(exist).State = EntityState.Modified;
                    context.SaveChanges();
                    return 1;
                }
            }
        }

        public dynamic GetNotDistUserInfo()
        {
            using (WorkLogContext context = new WorkLogContext())
            {
                var linq = from a in context.UserInfo
                           join b in context.UserPowerInfo on a.UserID equals b.ChilderID
                           into c
                           let d = c.FirstOrDefault()
                           join e in context.DepartmentInfo on a.DepartmentID equals e.DepartmentID
                           into f
                           let g = f.FirstOrDefault()
                           join h in context.PositionInfo on a.PositionID equals h.PositionID
                           into i
                           let j = i.FirstOrDefault()
                           select new {
                               a.UserID,
                               a.AccountName,
                               a.RealName,
                               a.MobilePhone,
                               a.PositionID,
                               a.DepartmentID,
                               g.DepartmentName,
                               j.PositionName,
                               IsNotDist=d==null?true:false
                           };
                linq = linq.Where(p => p.IsNotDist == true);
                return linq.ToList();
            }
        }

        public dynamic Get(int userID)
        {
            using (WorkLogContext context = new WorkLogContext())
            {
                var linq = from a in context.UserInfo
                           join b in context.UserPowerInfo on a.UserID equals b.ChilderID
                           into c
                           let d = c.Select(s=>s.UserID).ToList()
                           join e in context.DepartmentInfo on a.DepartmentID equals e.DepartmentID
                           into f
                           let g = f.FirstOrDefault()
                           join h in context.PositionInfo on a.PositionID equals h.PositionID
                           into i
                           let j = i.FirstOrDefault()
                           select new
                           {
                               a.UserID,
                               a.AccountName,
                               a.RealName,
                               a.MobilePhone,
                               a.PositionID,
                               a.DepartmentID,
                               g.DepartmentName,
                               j.PositionName,
                               a.IsManager,
                               ParentIDs=string.Join(",",d)
                           };
                if (userID > 0)
                {
                    linq= linq.Where(p => p.UserID == userID);
                }
                return linq.ToList();
            }
        }

        public List<dynamic> GetUserByPage(int userID,int? departmentID,int? positionID,bool? isIsChilder, RequstPageBase page)
        {
            using (WorkLogContext context = new WorkLogContext())
            {
                var linq = from a in context.UserInfo
                           join e in context.DepartmentInfo on a.DepartmentID equals e.DepartmentID
                           into f
                           let g = f.FirstOrDefault()
                           join k in context.PositionInfo on a.PositionID equals k.PositionID
                           into l
                           let m = l.FirstOrDefault()
                           join h in context.UserPowerInfo on new { UserID=userID,ChilderID=a.UserID } equals new { h.UserID,h.ChilderID }
                           into i
                           let j = i.FirstOrDefault()
                           select new
                           {
                               a.UserID,
                               a.AccountName,
                               a.MobilePhone,
                               a.RealName,
                               a.PositionID,
                               a.DepartmentID,
                               g.DepartmentName,
                               m.PositionName,
                               m.Sort,
                               IsChilder = j == null ? false : true,
                           };
                if (userID > 0)
                {
                    linq = linq.Where(p => p.UserID != userID);
                }

                if (departmentID.HasValue && departmentID>0)
                {
                    linq = linq.Where(p => p.DepartmentID == departmentID);
                }

                if (positionID.HasValue && positionID > 0)
                {
                    linq = linq.Where(p => p.PositionID == positionID);
                }
                if (isIsChilder.HasValue)
                {
                    linq = linq.Where(p => p.IsChilder == isIsChilder);
                }

                if (!string.IsNullOrEmpty(page.Keyword))
                {
                    linq = linq.Where(p => p.AccountName == page.Keyword || p.RealName.Contains(page.Keyword));
                }
                int startRow = page.PageSize * (page.PageIndex - 1);
                page.TotalRows= linq.Count();
                linq=linq.OrderBy(o => o.Sort).Skip(startRow).Take(page.PageSize);
                return linq.ToList<dynamic>();
            }
        }
    }
}
